package cn.fansunion.concurrent.executorservice;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//获得Future的值，如果还没返回，就等待
public class FutureTaskTest {

	public static void main(String[] args) {
		// 【强制】线程池不允许使用 Executors ExecutorsExecutors
		// 去创建，而是通过 去创建，而是通过 去创建，而是通过 ThreadPoolExecutor
		// ThreadPoolExecutor的方式，这样 的方式，这样 的处理方式让写同学更加明确线程池运行规则，避资源耗尽风险。
		int nThreads = 5;
		ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue<Runnable>(1000));
		List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(10);
		for (int index = 1; index <= 10; index++) {
			Integer num = new Random().nextInt(10);
			System.out.println(String.format("index:%s,num=%s", index,num));
			FutureTask<Integer> task = new FutureTask<>(new Callable<Integer>() {

				public Integer call() throws Exception {
					int maxSleepNum = 10;
					Integer sleepNum = new Random().nextInt(maxSleepNum);
					System.out.println(String.format("SleepNum:%s", sleepNum));
					Thread.sleep(sleepNum*1000);
					return num;
				}

			});
			if(!executor.isShutdown()){
				executor.submit(task);
			}
			taskList.add(task);
		}
		Integer sum = 0;
		for (FutureTask<Integer> task : taskList) {
			try {
				//阻塞,Waits if necessary for the computation to complete, and then retrieves its result.
				Integer num = task.get();
				System.out.println(String.format("num=%s",num));
				sum += num;
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}

		}
		executor.shutdownNow();
		System.out.println(sum);
	}

}
